package com.jinbiao.quasar.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.jinbiao.quasar.annotate.OperationLog;
import com.jinbiao.quasar.constant.MsgType;
import com.jinbiao.quasar.constant.RedisBucketKey;
import com.jinbiao.quasar.dto.*;
import com.jinbiao.quasar.model.SysNotice;
import com.jinbiao.quasar.model.SysNoticeToUser;
import com.jinbiao.quasar.model.SysUser;
import com.jinbiao.quasar.util.AjaxJson;
import com.jinbiao.quasar.util.RedisUtil;
import com.jinbiao.quasar.websocket.NoticeAndMsgListener;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.data.annotation.Tran;
import org.noear.solon.extend.sqltoy.annotation.Db;
import org.sagacity.sqltoy.dao.SqlToyLazyDao;
import org.sagacity.sqltoy.model.EntityQuery;
import org.sagacity.sqltoy.model.EntityUpdate;
import org.sagacity.sqltoy.model.Page;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Controller
@OperationLog
public class NoticeController {
    @Db
    SqlToyLazyDao dao;
    @Mapping("/notice/get-notice-list")
    public AjaxJson getNoticeList(int page, int pageSize, NoticeFilterDto notice){
        String userId = StpUtil.getLoginIdAsString();
        String userStr = RedisUtil.getClient().getBucket().get(RedisBucketKey.USER + userId);
        if (StrUtil.isNotEmpty(userStr)) {
            SysUser user = JSONUtil.toBean(userStr, SysUser.class);
            notice.setNoticeToUser(user.getUsername());
        }
        return AjaxJson.getSuccessData(dao.findPageBySql(new Page(pageSize,page),"sysNoticeList",notice));
    }
    @Mapping("/notice/get-recieve-notice-list")
    public AjaxJson getRecieveNoticeList(int page, int pageSize, NoticeFilterDto notice){
        String userId = StpUtil.getLoginIdAsString();
        String userStr = RedisUtil.getClient().getBucket().get(RedisBucketKey.USER + userId);
        if (StrUtil.isNotEmpty(userStr)) {
            SysUser user = JSONUtil.toBean(userStr, SysUser.class);
            notice.setNoticeToUser(user.getUsername());
        }
        Page<NoticeResultDto> pageResult =  dao.findPageBySql(new Page(pageSize,page),"sysNoticeList",BeanUtil.beanToMap(notice),NoticeResultDto.class);
        if(CollectionUtil.isNotEmpty(pageResult.getRows())){
            pageResult.getRows().stream().forEach(item->{
                item.setNoticeToUser(dao.findEntity(SysNoticeToUser.class,EntityQuery.create().where("notice_id = ?").values(item.getNoticeId())));
            });
        }
        return AjaxJson.getSuccessData(pageResult);
    }

    @Mapping("/notice/get-create-notice-list")
    public AjaxJson getNoticeListForCreate(int page, int pageSize, NoticeFilterDto notice){
        if(!StrUtil.equals(StpUtil.getLoginIdAsString(),"1"))
        notice.setCreatedBy(StpUtil.getLoginIdAsString());
        return AjaxJson.getSuccessData(dao.findPageBySql(new Page(pageSize,page),"sysNoticeList",notice));
    }
    @Mapping("/notice/add-notice")
    @Tran
    public AjaxJson addNotice(NoticeDto noticeDto){
        SysNotice notice = (SysNotice)noticeDto;
        String noticeId = IdUtil.getSnowflakeNextIdStr();
        notice.setNoticeId(noticeId);
        notice.setNoticeSent("yesNo_no");
        dao.save(notice);
        if(StrUtil.equals(noticeDto.getNoticeToUserType(),"some")&&CollectionUtil.isNotEmpty(noticeDto.getNoticeToUser())){
            List<SysNoticeToUser> noticeToUsers = new ArrayList<>();
            noticeDto.getNoticeToUser().stream().forEach(noticeToUser->{
                SysNoticeToUser item = new SysNoticeToUser();
                item.setUserRead("yesNo_no");
                item.setNoticeId(noticeId);
                item.setToUser(noticeToUser);
                noticeToUsers.add(item);
            });
            if(CollectionUtil.isNotEmpty(noticeToUsers))
            dao.saveAll(noticeToUsers);
        }else{
            if(StrUtil.equals(noticeDto.getNoticeToUserType(),"all")){
                List<SysNoticeToUser> noticeToUsers = new ArrayList<>();
                dao.findEntity(SysUser.class,EntityQuery.create(),SysUser.class).stream().forEach(user->{
                    SysNoticeToUser item = new SysNoticeToUser();
                    item.setUserRead("yesNo_no");
                    item.setNoticeId(noticeId);
                    item.setToUser(user.getUsername());
                    noticeToUsers.add(item);
                });
                if(CollectionUtil.isNotEmpty(noticeToUsers))
                    dao.saveAll(noticeToUsers);
            }
        }
        return AjaxJson.getSuccess("操作成功");
    }

    @Mapping("/notice/query-notice-by-id")
    @Tran
    public AjaxJson queryNoticeById(String id){
        SysNotice notice = new SysNotice();
        notice.setId(id);
        List<SysNotice> noticeList = dao.findBySql("sysNoticeList",notice);
        if(CollectionUtil.isNotEmpty(noticeList)){
            SysNotice result = noticeList.get(0);
            List<SysNoticeToUser> toUsers = dao.findBySql("sysNoticeToUserList",new SysNoticeToUser(result.getNoticeId()));
            NoticeDto noticeDto = new NoticeDto();
            BeanUtil.copyProperties(result,noticeDto,false);
            noticeDto.setNoticeToUser(toUsers.stream().map(SysNoticeToUser::getToUser).collect(Collectors.toList()));
            String userId = StpUtil.getLoginIdAsString();
            String userStr = RedisUtil.getClient().getBucket().get(RedisBucketKey.USER + userId);
            if (StrUtil.isNotEmpty(userStr)) {
                SysUser user = JSONUtil.toBean(userStr, SysUser.class);
                dao.updateByQuery(SysNoticeToUser.class, EntityUpdate.create().set("userRead", "yesNo_yes").where("notice_id=? and to_user=?").values(result.getNoticeId(),user.getUsername()));
                NoticeAndMsgListener.sendMsg(user.getUsername(), JSONUtil.toJsonStr(new NoticeAndChatDto(StrUtil.equals(result.getNoticeToUserType(),"some")?MsgType.CUSTOM_NOTICE:MsgType.SYSTEM_NOTICE)));
            }else{
                return AjaxJson.getError("当前登录人信息错误,请重新登录后再试！");
            }
            return AjaxJson.getSuccessData(noticeDto);
        }else{
            return AjaxJson.getSuccess();
        }
    }

    @Mapping("/notice/delete-notice-by-id")
    @Tran
    public AjaxJson deleteNoticeById(String id){
        SysNotice notice = new SysNotice();
        notice.setId(id);
        List<SysNotice> noticeList = dao.findBySql("sysNoticeList",notice);
        if(CollectionUtil.isNotEmpty(noticeList)) {
            noticeList.stream().forEach(item->{
                dao.deleteByQuery(SysNotice.class, EntityQuery.create().where("id = ?").values(item.getId()));
                dao.deleteByQuery(SysNoticeToUser.class,EntityQuery.create().where("notice_id = ?").values(item.getNoticeId()));
            });
            return AjaxJson.getSuccess("处理成功");
        }
        return AjaxJson.getError("操作失败");
    }

    @Mapping("/notice/send-notice")
    @Tran
    public AjaxJson sendNotice(String id){
        SysNotice notice = new SysNotice();
        notice.setId(id);
        List<SysNotice> noticeList = dao.findBySql("sysNoticeList",notice);
        if(CollectionUtil.isNotEmpty(noticeList)) {
            noticeList.stream().forEach(item->{
                item.setNoticeSent("yesNo_yes");
                dao.updateByQuery(SysNotice.class, EntityUpdate.create().set("noticeSent",item.getNoticeSent()).where("id = ?").values(item.getId()));
                List<SysNoticeToUser> toUsers = dao.findEntity(SysNoticeToUser.class,EntityQuery.create().where("notice_id=?").values(item.getNoticeId()));
                if(CollectionUtil.isNotEmpty(toUsers)){
                    NoticeAndMsgListener.sendMsg(toUsers.stream().map(SysNoticeToUser::getToUser).collect(Collectors.toList()), JSONUtil.toJsonStr(new NoticeAndChatDto(StrUtil.equals(item.getNoticeToUserType(),"some")?MsgType.CUSTOM_NOTICE:MsgType.SYSTEM_NOTICE)));
                }
            });
            return AjaxJson.getSuccess("处理成功");
        }
        return AjaxJson.getError();
    }
    @Mapping("/notice/query-notice-read-by-id")
    @Tran
    public AjaxJson queryNoticeReadById(String id){
        SysNotice notice = new SysNotice();
        notice.setId(id);
        List<SysNotice> noticeList = dao.findBySql("sysNoticeList",notice);
        if(CollectionUtil.isNotEmpty(noticeList)){
            SysNotice result = noticeList.get(0);
            String userId = StpUtil.getLoginIdAsString();
            String userStr = RedisUtil.getClient().getBucket().get(RedisBucketKey.USER + userId);
            if (StrUtil.isNotEmpty(userStr)) {
                SysUser user = JSONUtil.toBean(userStr, SysUser.class);
                dao.updateByQuery(SysNoticeToUser.class, EntityUpdate.create().set("userRead", "yesNo_yes").where("notice_id=? and to_user=?").values(result.getNoticeId(),user.getUsername()));
                NoticeAndMsgListener.sendMsg(user.getUsername(), JSONUtil.toJsonStr(new NoticeAndChatDto(StrUtil.equals(result.getNoticeToUserType(),"some")?MsgType.CUSTOM_NOTICE:MsgType.SYSTEM_NOTICE)));
            }else{
                return AjaxJson.getError("当前登录人信息错误,请重新登录后再试！");
            }
            List<SysNoticeToUser> toUsers = dao.findBySql("sysNoticeToUserList",new SysNoticeToUser(result.getNoticeId()));
            NoticeDto noticeDto = new NoticeDto();
            BeanUtil.copyProperties(result,noticeDto,false);
            noticeDto.setNoticeToUser(toUsers.stream().map(SysNoticeToUser::getToUser).collect(Collectors.toList()));
            return AjaxJson.getSuccessData(noticeDto);
        }else{
            return AjaxJson.getSuccess();
        }
    }
}
